package com.yifi.common.plugins.influxDB;

import com.influxdb.client.InfluxDBClient;
import com.influxdb.client.WriteApiBlocking;
import com.influxdb.client.domain.WritePrecision;
import com.influxdb.client.write.Point;
import com.influxdb.query.FluxColumn;
import com.influxdb.query.FluxRecord;
import com.influxdb.query.FluxTable;
import com.jfinal.plugin.activerecord.Record;
import org.apache.iotdb.tsfile.read.common.Field;
import org.apache.poi.ss.formula.functions.T;

import java.time.Instant;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @author 姚善利
 * @classname com.yifi.common.plugins.influxDB
 * @description
 * @date 2022/11/3 8:56
 */
public class InfluxDBUtils {

    public static InfluxDBClient client;
    public static String bucket;
    public static String org;

    public InfluxDBUtils() {

    }
    public static void init(InfluxDBClient _client)
    {
        if(_client==null)
        {
            throw new IllegalArgumentException("InfluxDBClient can not be null");
        }
        else
        {
            client=_client;
        }
    }
    public static void init(InfluxDBClient _client,String _bucket,String _org)
    {
        if(_client==null)
        {
            throw new IllegalArgumentException("InfluxDBClient can not be null");
        }
        else
        {
            client=_client;
            bucket=_bucket;
            org=_org;
        }
    }

    public static void close()
    {
        if(client!=null)
        {
            client.close();
        }
    }

    /**
     *  使用influxdb线路协议写入数据
     * @param data
     */
    public void writeRecord(String data)
    {
        //String data = "mem,host=host1 used_percent=23.43234543";
        WriteApiBlocking writeApi=client.getWriteApiBlocking();
        writeApi.writeRecord(bucket,org, WritePrecision.NS,data);
    }
    /**
     *  使用influxdb线路协议写入数据
     * @param datas
     */
    public static void writeRecords(List<String> datas)
    {
        //String data = "mem,host=host1 used_percent=23.43234543";
        WriteApiBlocking writeApi=client.getWriteApiBlocking();
        writeApi.writeRecords(bucket,org, WritePrecision.NS,datas);
    }

    /**
     * 使用数据插入节点
     * @param mem
     * @param tags
     * @param fields
     */
    public static void writePoint(String mem, HashMap<String,String> tags, HashMap<String,Object> fields)
    {
        Point point=Point.measurement(mem);
        if(tags!=null)
        {
            point.addTags(tags);
        }
        point.addFields(fields);
        point.time(Instant.now(),WritePrecision.NS);

        WriteApiBlocking writeApi=client.getWriteApiBlocking();
        writeApi.writePoint(bucket,org,point);
    }

    public static void writeMeasurement(Class<T> mem)
    {
        WriteApiBlocking writeApi=client.getWriteApiBlocking();
        writeApi.writeMeasurement(bucket,org,WritePrecision.NS,mem);
    }

    /**
     * 写入 pojo的list集合
     * @param list
     */
    public static void writeMeasurements(List<T> list)
    {
        WriteApiBlocking writeApi=client.getWriteApiBlocking();
        writeApi.writeMeasurement(bucket,org,WritePrecision.NS,list);
    }

    /**
     *  查询数据
     * @param query
     * @return
     */
    public static List<FluxTable> query(String query)
    {
        List<FluxTable> tables = client.getQueryApi().query(query, org);
        return tables;
    }

    /**
     * 查询结果影射成为POJO
     * @param T
     * @param query
     * @return
     */
    public static List<T> query(Class<T> T,String query)
    {
        /*String flux = "from(bucket: \"wxm-influx\")\n" +
                "  |> range(start: 2022-03-12T08:18:04Z,stop:2022-03-13T08:19:05Z)\n" +
                "  |> filter(fn:(r)=>(r.owner==\"wxm\"))";*/
        List<T> list = client.getQueryApi().query(query, T.class);
        //list.forEach(System.out::println);
        return list;
    }

    /**
     * 删除开始结束时间
     * @param start
     * @param stop
     */
    public static void delete(OffsetDateTime start,OffsetDateTime stop)
    {
        client.getDeleteApi().delete(start,stop,"",bucket,org);
    }

    /**
     *   List<FluxTable> 转 List<Record>
     * @param tables 单设备的数据集合
     * @return
     */
    public static List<Record> ToListRecord(List<FluxTable> tables){
        List<Record> list=new ArrayList<Record>();
        for (FluxTable fluxTable : tables) {
            List<FluxColumn> listCols = fluxTable.getColumns();     //数据信息
            List<FluxRecord> records = fluxTable.getRecords();
            for (FluxRecord fluxRecord : records) {
                Instant time=fluxRecord.getTime();
                Record record=new Record();
                record.set("time",time);

                String colName=fluxRecord.getField();
                Object obj = fluxRecord.getValue();
                record.set(colName,obj);

                list.add(record);
            }
        }
        return list;
    }

    /**
     *  查询出单参数的时间折线图数据集
     * @param tables    单设备的数据集合
     * @param field
     * @return
     */
    public static List<Object> ToList(List<FluxTable> tables,String field){
        List<Object> data;
        List<Object> list_data = new ArrayList<Object>();
        for (FluxTable fluxTable : tables) {
            List<FluxRecord> records = fluxTable.getRecords();
            for (FluxRecord fluxRecord : records) {
                data=new ArrayList<Object>();
                data.add(fluxRecord.getTime());
                data.add(fluxRecord.getValue());
                //System.out.println(fluxRecord.getTime() + ": " + fluxRecord.getValueByKey(field));
                list_data.add(data);
            }
        }
        return list_data;
    }

}

